﻿using IWshRuntimeLibrary;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace 打开
{
    public class DataManager
    {               
        ///Data 格式: startlocation,1,2 起始位置,横坐标,纵坐标    button,0,0,path  按钮,在多少页,在第几个按钮,指向的文件路径


        /// <summary>文件默认位置</summary>
        public static string DataPath { get; } = System.AppDomain.CurrentDomain.BaseDirectory + "/data.dat";

        /// <summary>程序起始位置</summary>
        public static Point startLocation = new Point(50,100);

        /// <summary>页面数据数组</summary>
        public static ButtonData[,] buttonData = new ButtonData[4, 15];

        /// <summary>按钮数据类 </summary>
        public class ButtonData
        {

            /// <summary>按钮路径</summary>
            public string Path;

            /// <summary>按钮图标</summary>
            public Image Icon;

            /// <summary>按钮类型</summary>
            public ButtonKind buttonKind;

            /// <summary>按钮类型</summary>
            public enum ButtonKind
            {
                None = 0,
                File = 1,
                Directory = 2,
                WebPage = 3,
                未知 = 4,
            }


            public ButtonData(string path)
            {
                try
                {
                    Path = path;
                    buttonKind = GetKind(path);
                    Icon = GetIcon(path, buttonKind);
                }
                catch
                {
                    Path = "";
                    buttonKind = ButtonKind.None;
                    Icon = Resource.NullFile_icon;
                }

            }

            public ButtonData(string path, ButtonKind kind, Image icon)
            {
                Path = path;
                buttonKind = kind;
                Icon = icon;
            }

            public static ButtonData None
            {
                get { return new ButtonData("", ButtonKind.None, Resource.NullFile_icon); }
            }

            public static ButtonData CreatNewButtonData(string path)
            {
                string filePath = GetFilePath(path);
                ButtonKind fileKind = GetKind(filePath);
                Image fileIcon = GetIcon(filePath, fileKind);

                return new ButtonData(filePath, fileKind, fileIcon);
            }

            public override string ToString()
            {
                //return base.ToString();
                return "路径: " + Path + " 类型: " + buttonKind;
            }

        }


        public DataManager()
        {
            //如果数据文件不存在 则创建数据文件
            if (!System.IO.File.Exists(DataPath))
            {
                TextWriter tw = new StreamWriter(DataPath);
                tw.WriteLine("");
                tw.Flush();
                tw.Close();
            }

            FileStream fs = new FileStream(DataPath, FileMode.Open);

            //打开数据文件
            StreamReader sr = new StreamReader(fs, Encoding.Default);

            //可用数据不为空就循环
            while (sr.Peek() != -1)
            {
                //存放数据到datas数组中,每行以逗号拆分字符串
                string[] datas = sr.ReadLine().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

                //Console.WriteLine(datas.Length);

                //如果此行第一个数据为 startlocation 则将后两个数据赋值给startlocation
                if (isStartLocation(datas))
                {
                    try
                    {
                        startLocation.X = int.Parse(datas[1]);
                        startLocation.Y = int.Parse(datas[2]);
                    }
                    catch
                    {
                        startLocation = new Point(50, 100);
                    }

                }

                //如果是数据行而且是有效按钮数据行 则将数据赋值给对应的buttondata
                if (isValidButtonLine(datas))
                {
                    buttonData[int.Parse(datas[1]), int.Parse(datas[2])] = new ButtonData(datas[3]);
                }
            }

            sr.Close();

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    ButtonData bd = buttonData[i, j];
                    if (bd == null)
                    {
                        bd = buttonData[i, j] = ButtonData.None;
                    }
#if DEBUG
                    Console.WriteLine(buttonData[i,j].ToString());
#endif
                }
            }

        }

        public static void DataWriter()
        {
            TextWriter tw = new StreamWriter(DataPath);

            tw.WriteLine("startlocation,{0},{1}", startLocation.X, startLocation.Y);

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    if ((buttonData[i, j].buttonKind != ButtonData.ButtonKind.None) && (buttonData[i, j].buttonKind != ButtonData.ButtonKind.未知))
                    {
                        tw.WriteLine("button,{0},{1},{2}", i.ToString(), j.ToString(), buttonData[i, j].Path);
                    }
                }
                tw.WriteLine("");
            }

            tw.Flush();
            tw.Close();
        }

        

        //判断是否是起始位置数据行
        private bool isStartLocation(string[] strs)
        {
            if (strs.Length > 2)
            {
                if (strs[0].ToLower() == "startlocation")
                {
                    return true;
                }
            }
            return false;
        }

        //判断是否是按钮数据行
        private bool isButtonLine(string[] strs)
        {
            if(strs.Length>2)
            {
                if (strs[0].ToLower() == "button")
                {
                    return true;
                }
            }
            return false;
        }

        //判断是否是有效按钮数据行
        private bool isValidButtonLine(string[] strs)
        {
            if (isButtonLine(strs))
            {
                if (strs.Length > 3)
                {
                    return true;
                }
            }
            return false;
        }

       

        /// <summary>获取最终文件路径</summary>
        public static string GetFilePath(string path)
        {
            //获取扩展名
            string exname = Get_Extension(path);

            //根据扩展名返回路径
            if (exname == @".lnk")
            {
                Console.WriteLine("获取路径_快捷方式");

                //递归是为了获取多重快捷方式的真实地址
                return GetFilePath(Get_LnkPath(path));
            }
            else if (exname == @".url")
            {
                Console.WriteLine("获取路径_网页URL");

                return path;
            }
            else
            {
                if (isFileExist(path))
                    Console.WriteLine("获取路径_文件");
                else if (isDirectoryExist(path))
                    Console.WriteLine("获取路径_文件夹");

                return path;
            }


        }

        /// <summary>获取类型</summary>
        /// <returns></returns>
        public static ButtonData.ButtonKind GetKind(string path)
        {
            if (isFileExist(path))
            {
                return ButtonData.ButtonKind.File;
            }

            if (isDirectoryExist(path))
            {
                return ButtonData.ButtonKind.Directory;
            }

            return ButtonData.ButtonKind.None;

        }

        /// <summary>获取图标</summary>
        /// <param name="path">路径</param>
        /// <param name="type">类型</param>
        public static Image GetIcon(string path, ButtonData.ButtonKind type)
        {

            //实例化SHFILEINFO类
            SHFILEINFO shfi = new SHFILEINFO();

            if (type == ButtonData.ButtonKind.None || type == ButtonData.ButtonKind.未知)
            {
                return Resource.NullFile_icon;
            }

            //获取文件夹的图标及类型
            SHGetFileInfo(path, (uint)0x80, ref shfi, (uint)Marshal.SizeOf(shfi), (uint)(0x100 | 0x400));

            //转换格式
            Image icon = Icon.FromHandle(shfi.hIcon).ToBitmap();

            //销毁图标
            DestroyIcon(shfi.hIcon);

            return icon;

        }



        /// <summary>获取扩展名</summary>
        private static string Get_Extension(string path)
        {
            //Console.WriteLine("文件后缀名： " + Path.GetExtension(path));
            return System.IO.Path.GetExtension(path).ToLower();
        }

        /// <summary>获取快捷方式目标地址</summary>
        private static string Get_LnkPath(string path)
        {
            IWshShortcut shortcut = (IWshShortcut)new WshShell().CreateShortcut(path);
            return shortcut.TargetPath;
        }

        /// <summary>获取文件图标</summary>
        private static Image Get_FileIcon(string path)
        {
            return Icon.ExtractAssociatedIcon(path).ToBitmap();
        }

        /// <summary>获取网页图标</summary>
        private static Image Get_WebIcon(string path)
        {
            HttpWebRequest vHttpWebRequest = (HttpWebRequest)WebRequest.Create(path + @"/favicon.ico");
            HttpWebResponse vHttpWebResponse = (HttpWebResponse)vHttpWebRequest.GetResponse();
            Image icon = Image.FromStream(vHttpWebResponse.GetResponseStream());
            vHttpWebResponse.Close();
            return icon;
        }

        /// <summary>判断文件是否存在</summary>
        private static bool isFileExist(string path)
        {
            return System.IO.File.Exists(path);
        }

        /// <summary>判断文件夹是否存在</summary>
        private static bool isDirectoryExist(string path)
        {
            return System.IO.Directory.Exists(path);
        }

        [DllImport("shell32.dll", EntryPoint = "SHGetFileInfo")]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttribute, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint Flags);
        [DllImport("User32.dll", EntryPoint = "DestroyIcon")]
        public static extern int DestroyIcon(IntPtr hIcon);
        [DllImport("shell32.dll")]
        public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);
        [StructLayout(LayoutKind.Sequential)]

        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }

    }
}
